<?php

namespace app\admin\service;


use app\admin\model\Illegal;
use app\admin\model\Operation;
use app\admin\model\OperationRead;
use think\Db;

class IllegalApiService extends BaseService
{
    public function __construct()
    {
        $this->model = (new Operation);
    }

    public function notice()
    {

    }

    public function lists($userId, $param)
    {
        $page     = isset($param['page']) ? $param['page'] : 1;
        $pageSize = isset($param['pageSize']) ? $param['pageSize'] : 10;
        $query    = $this->getQuery($userId, $param);
        $data     = $query
            ->field(
                [
                    'id',
                    'operation_no',
                    'operation_category',
                    'exception_category',
                    'area_id',
                    'address',
                    'description',
                    'images',
                    'diff_points',
                    'longitude',
                    'latitude',
                    'create_user',
                    'create_time',
                    'street_id',
                    'verify_user',
                    'verify_time'
                ]
            )
            ->with(
                [
                    'user' => function ($query) {
                        $query->field(['id', 'realname', 'mobile']);
                    }
                ]
            )
            ->order('id', 'desc')
            ->page($page, $pageSize)
            ->select();
        $abnormalServer = new AbnormalService();
        $abnormalTree   = $abnormalServer->tree([], 0);

        $data->each(
            function ($val) use ($abnormalServer, $abnormalTree) {
                $val['exception_category'] = $abnormalServer->getTreeById($val['exception_category'], $abnormalTree);
                if ($val['verify_user']) {
                    $val['verify_time'] = date('Y-m-d H:i:s', $val['verify_time']);
                }
                $val['images'] = $val['images'] ? json_decode($val['images'], true) : [];
                $val['diff_points'] = $val['diff_points'] ? json_decode($val['diff_points'], true) : [];
                $val['mark'] = [
                    'longitude' => $val['longitude'],
                    'latitude' => $val['latitude']
                ];
            }
        );

        return $data;
    }

    public function total($userId, $param)
    {
        $arr  = [
            'wait'      => 0,
            'processed' => 1
        ];
        $data = [];
        foreach ($arr as $key => $val) {
            $param['verify_status'] = $val;
            $query                  = $this->getQuery($userId, $param);
            $data[$key]             = $query->count('id');
        }

        return $data;
    }

    public function detail($id, $userId)
    {
        $data = $this->model
            ->field(
                [
                    'id',
                    'operation_no',
                    'operation_category',
                    'exception_category',
                    'area_id',
                    'address',
                    'description',
                    'images',
                    'credential',
                    'diff_points',
                    'longitude',
                    'latitude',
                    'create_user',
                    'create_time',
                    'street_id',
                    'verify_user',
                    'verify_time',
                ]
            )
            ->with(
                [
                    'user' => function ($query) {
                        $query->field(['id', 'realname', 'mobile']);
                    }
                ]
            )
            ->find($id);

        if (empty($data)) {
            return [];
        }

        $abnormalServer             = new AbnormalService();
        $data['exception_category'] = $abnormalServer->getTreeById($data['exception_category']);
        if ($data['verify_user']) {
            $data['verify_time'] = date('Y-m-d H:i:s', $data['verify_time']);
        }
        $data['mark'] = [
            'longitude' => $data['longitude'],
            'latitude' => $data['latitude']
        ];
        $read = (new OperationRead)->where('operation_id', $id)->where('user_id', $userId)->value('id');
        $data['read'] = $read ? 1 : 0;

        return $data;
    }

    public function read($id, $userId)
    {
        Db::startTrans();
        try {
            $exists = (new OperationRead)
                ->where('operation_id', $id)
                ->where('user_id', $userId)
                ->lock(true)
                ->value('id');
            if ($exists) {
                throw new \Exception('该工作已经阅读过');
            }
            (new OperationRead)->insert(['user_id' => $userId, 'operation_id' => $id, 'create_time' => time()]);
            Db::commit();

            return true;
        } catch (\Exception $e) {
            Db::rollback();

            return $e->getMessage();
        }
    }

    public function save($userId, $param)
    {
        Db::startTrans();
        try {
            $info = $this->model->lock(true)->find($param['id']);
            if (empty($info)) {
                throw new \Exception('数据不存在');
            }
            if ($info->verify_user) {
                throw new \Exception('该工作已经被确认，无法再次确认');
            }
            $info->operation_category = $param['res'];
            $info->status = 2;
            if (!empty($param['credential'])) {
                $info->credential = json_encode($param['credential']);
                $info->penalty = 1;
            }
            $info->verify_user        = $userId;
            $info->verify_time        = time();
            $info->save();
            Db::commit();

            return true;
        } catch (\Exception $e) {
            Db::rollback();

            return $e->getMessage();
        }
    }

    public function statistics($userId)
    {
        $arr  = [
            'today' => [strtotime('today'), time()],
            'total' => null
        ];
        $data = [];
        foreach ($arr as $key => $val) {
            $param['my']          = true;
            $param['verify_time'] = $val;
            $query                = $this->getQuery($userId, $param);
            $data[$key]           = $query->count('id');
        }

        return $data;
    }

    public function my($userId, $param)
    {
        $param['my'] = 1;

        return $this->lists($userId, $param);
    }

    private function getQuery($userId, $param)
    {
        $query = (clone $this->model)
            ->where('mark', 1)
            ->whereRaw('json_contains(verify_user_list, \'' . $userId . '\')');
        if (!empty($param['area'])) {
            $query->where('area_id', $param['area']);
        }
        if (isset($param['verify_status'])) {
            if ($param['verify_status'] == 1) {
                $query->where('verify_user', '<>', 0);
            } else {
                $query->where('verify_user', 0);
            }
        }
        if (!empty($param['my'])) {
            $query->where('verify_user', $userId);
        }
        if (!empty($param['verify_time'])) {
            $param['verify_time'] = array_map(
                function ($val) {
                    return is_numeric($val) ? $val : strtotime($val);
                },
                $param['verify_time']
            );
            $query->whereBetween('verify_time', $param['verify_time']);
        }
        if (!empty($param['keyword'])) {
            $query->where(
                function ($query) use ($param) {
                    $query->whereOr('description', 'like', '%' . $param['keyword'] . '%')
                        ->whereOr('address', 'like', '%' . $param['keyword'] . '%')
                        ->whereOr('operation_no', 'like', '%' . $param['keyword'] . '%');
                }
            );
        }

        return $query;
    }
}